import { SetupContext, computed, nextTick, reactive, ref, toRefs, unref, watch } from 'vue'
import { PageList, PaginationEmit, PaginationProps } from '../pagination-types'

export default function (props: PaginationProps, ctx: SetupContext<PaginationEmit>) {
  const { pageSize, selectOptions, showSelectOptions, total: dataTotal } = toRefs(props)

  const pageInfo = reactive({
    pageCurrInfo: {
      displayText: '1',
      pageNum: 1,
      pageIndex: 0
    },
    pagePrevInfo: {
      displayText: '1',
      pageNum: 1,
      pageIndex: 0
    },
    offsetIndex: 0,
    centerIndex: 0,
    centerNum: 0,
    intervalNum: { left: 0, right: 0 },
    centerBoth: { left: 0, right: 0 },
    listSize: 10,
    pageTotal: computed(() => Math.round(dataTotal.value / pageSize.value))
  })

  const moveRealInfo = computed(() => {
    const { pageCurrInfo, pagePrevInfo, listSize, pageTotal, intervalNum, centerBoth } = unref(pageInfo)
    pageInfo.centerIndex = Math.floor(listSize / 2)
    intervalNum.left = Math.floor((listSize - 4) / 2)
    intervalNum.right = Math.floor((listSize - 1 - 4) / 2)
    centerBoth.left = pageInfo.centerIndex
    centerBoth.right = Math.floor((listSize - 1) / 2)
    const offsetLeftIndex = pageCurrInfo.pageIndex - pageInfo.centerIndex

    if (pageCurrInfo.pageNum >= 1 + centerBoth.left && pageCurrInfo.pageNum <= pageTotal - centerBoth.right) {
      pageCurrInfo.pageIndex = pageInfo.centerIndex
    }
    // console.log('ccccccccccccc', pageCurrInfo.pageNum, offsetLeftIndex)
    pageInfo.centerNum = pageCurrInfo.pageNum - offsetLeftIndex
    pageCurrInfo.displayText = pageCurrInfo.pageNum + ''
    // console.log('xxxxxxxxxxx', pageInfo.centerIndex, pageCurrInfo.pageIndex, pageCurrInfo.pageNum, pageInfo.offsetIndex)
    pagePrevInfo.pageNum = pageCurrInfo.pageNum
    pagePrevInfo.pageIndex = pageCurrInfo.pageIndex
    pagePrevInfo.displayText = pageCurrInfo.displayText
    return pageCurrInfo
  })
  const pageList = computed<Array<PageList>>(() => {
    const { pageIndex, pageNum, displayText } = unref(moveRealInfo)
    const { centerIndex, centerNum, intervalNum, centerBoth, listSize, pageTotal } = unref(pageInfo)
    if (pageIndex < centerIndex) {
      let displayList: Array<PageList> = []
      displayList = Array.from({ length: listSize - 2 }).map((_, i) => {
        return { pageNum: i + 1, pageIndex: i, displayText: `${i + 1}` }
      })
      if (pageTotal > pageNum + centerNum) {
        displayList.push({ pageNum: pageNum + intervalNum.right + 1, pageIndex: centerIndex + intervalNum.right + 1, displayText: '...' })
      } else {
        displayList.push({ pageNum: pageNum + intervalNum.right + 1, pageIndex: listSize - 2, displayText: pageNum + intervalNum.right + 1 + '' })
      }
      displayList.push({ pageNum: pageTotal, pageIndex: listSize - 1, displayText: pageTotal + '' })
      // console.log('1111111111111111111', displayList)
      return displayList
    } else if (pageIndex > centerIndex) {
      let displayList: Array<PageList> = []
      displayList.push({ pageNum: 1, pageIndex: 0, displayText: '1' })
      let realPageNum: number = pageNum
      if (pageNum + centerBoth.right > pageTotal) {
        realPageNum = pageTotal - centerBoth.right
      }
      if (pageNum - centerIndex > 1) {
        displayList.push({ pageNum: realPageNum - intervalNum.left - 1, pageIndex: 1, displayText: '...' })
      } else {
        displayList.push({ pageNum: realPageNum - intervalNum.left - 1, pageIndex: 1, displayText: realPageNum - intervalNum.left - 1 + '' })
      }
      displayList.push(
        ...Array.from({ length: listSize - 3 }).map((_, i) => {
          return { pageNum: realPageNum - intervalNum.left + i, pageIndex: i + 2, displayText: `${realPageNum - intervalNum.left + i}` }
        })
      )
      displayList.push({ pageNum: pageTotal, pageIndex: listSize - 1, displayText: pageTotal + '' })
      // console.log('2222222222222222222', displayList, realPageNum)
      return displayList
    } else {
      let displayList: Array<PageList> = []
      displayList.push({ pageNum: 1, pageIndex: 0, displayText: '1' })
      if (pageNum - centerIndex > 1) {
        displayList.push({ pageNum: pageNum - intervalNum.left - 1, pageIndex: 1, displayText: '...' })
      } else {
        displayList.push({ pageNum: pageNum - intervalNum.left - 1, pageIndex: 1, displayText: pageNum - intervalNum.left - 1 + '' })
      }
      displayList.push(
        ...Array.from({ length: listSize - 4 }).map((_, i) => {
          return { pageNum: pageNum - intervalNum.left + i, pageIndex: i + 2, displayText: `${pageNum - intervalNum.left + i}` }
        })
      )
      if (pageTotal > pageNum + centerBoth.right) {
        displayList.push({ pageNum: pageNum + intervalNum.right + 1, pageIndex: centerIndex + intervalNum.right + 1, displayText: '...' })
      } else {
        displayList.push({ pageNum: pageNum + intervalNum.right + 1, pageIndex: listSize - 2, displayText: pageNum + intervalNum.right + 1 + '' })
      }
      displayList.push({ pageNum: pageTotal, pageIndex: listSize - 1, displayText: pageTotal + '' })
      // console.log('333333333333333333333', displayList, pageNum)
      return displayList
    }
  })
  watch(
    () => props.pageNum,
    () => {
      pageInfo.pageCurrInfo.pageNum = props.pageNum
    },
    {
      immediate: true
    }
  )
  watch(
    () => props.listSize,
    () => {
      pageInfo.listSize = props.listSize < 10 ? 10 : props.listSize
    },
    {
      immediate: true
    }
  )
  const activeRefs = ref<Array<HTMLDivElement>>([])
  const clickHandler = (e: Event, pageCurrInfo: PageList) => {
    // console.log(pageCurrInfo.pageIndex, pageCurrInfo.pageNum)
    const lastIndex = pageInfo.pageCurrInfo.pageIndex
    const firstDom = activeRefs.value[pageCurrInfo.pageIndex].parentElement as HTMLLIElement
    pageInfo.pageCurrInfo.pageIndex = pageCurrInfo.pageIndex
    pageInfo.pageCurrInfo.pageNum = pageCurrInfo.pageNum
    pageInfo.pageCurrInfo.displayText = pageCurrInfo.displayText
    FLIPAnimate(firstDom, lastIndex)
  }
  const changeNavHandle = (type: string) => {
    const { centerIndex, centerBoth, pageTotal, listSize, pageCurrInfo } = unref(pageInfo)
    const lastIndex = pageCurrInfo.pageIndex
    switch (type) {
      case 'first':
        {
          pageCurrInfo.pageIndex = 0
          pageCurrInfo.pageNum = 1
          const firstDom = activeRefs.value[pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
          FLIPAnimate(firstDom, lastIndex)
        }
        break
      case 'prev':
        if (pageCurrInfo.pageIndex > 0) {
          pageCurrInfo.pageIndex--
          pageCurrInfo.pageNum--
          const firstDom = activeRefs.value[pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
          FLIPAnimate(firstDom, lastIndex)
        }
        break
      case 'next':
        if (pageCurrInfo.pageNum < pageTotal) {
          pageCurrInfo.pageNum++
          if (pageCurrInfo.pageNum - centerBoth.left < 1 || pageTotal < pageCurrInfo.pageNum + centerBoth.right) {
            pageCurrInfo.pageIndex++
          } else {
            pageCurrInfo.pageIndex = centerIndex
          }
          const firstDom = activeRefs.value[pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
          FLIPAnimate(firstDom, lastIndex)
        }
        break
      case 'last':
        {
          pageCurrInfo.pageIndex = listSize - 1
          pageCurrInfo.pageNum = pageTotal
          const firstDom = activeRefs.value[pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
          FLIPAnimate(firstDom, lastIndex)
        }
        break
      default:
        {
          pageCurrInfo.pageIndex = 0
          pageCurrInfo.pageNum = 1
          const firstDom = activeRefs.value[pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
          FLIPAnimate(firstDom, lastIndex)
        }
        break
    }
  }
  const FLIPAnimate = (firstDom: HTMLElement, index: number) => {
    if (index === pageInfo.pageCurrInfo.pageIndex) return
    nextTick(() => {
      const lastDom = activeRefs.value[index].parentElement as HTMLLIElement
      const invert = {
        left: lastDom.offsetLeft - firstDom.offsetLeft,
        top: lastDom.offsetTop - firstDom.offsetTop
      }
      const keyframes = [
        {
          transform: `translate(${invert.left}px, ${invert.top}px)`
        },
        {
          transform: 'translate(0, 0)'
        }
      ]
      const options = {
        duration: 300,
        easing: 'cubic-bezier(0,0,0.32,1)'
      }
      firstDom.animate(keyframes, options)
    })
  }
  const changeInputHandle = (pNum: any) => {
    pNum = parseInt(pNum)
    const { centerIndex, centerBoth, pageTotal, listSize } = unref(pageInfo)
    if (pNum > pageTotal) {
      return
    }
    for (let index = 0; index < pageList.value.length; index++) {
      const element = pageList.value[index]
      if (element.pageNum === pNum) {
        const lastIndex = pageInfo.pageCurrInfo.pageIndex
        pageInfo.pageCurrInfo.pageIndex = element.pageIndex
        pageInfo.pageCurrInfo.pageNum = element.pageNum
        const firstDom = activeRefs.value[pageInfo.pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
        FLIPAnimate(firstDom, lastIndex)
        return
      }
    }
    const lastIndex = pageInfo.pageCurrInfo.pageIndex
    if (pNum - centerBoth.left < 1) {
      pageInfo.pageCurrInfo.pageIndex = pNum - 1
    } else if (pageTotal < pNum + centerBoth.right) {
      pageInfo.pageCurrInfo.pageIndex = listSize - (pageTotal - pNum)
    } else {
      pageInfo.pageCurrInfo.pageIndex = centerIndex
    }
    pageInfo.pageCurrInfo.pageNum = pNum
    const firstDom = activeRefs.value[pageInfo.pageCurrInfo.pageIndex]?.parentElement as HTMLLIElement
    FLIPAnimate(firstDom, lastIndex)
  }
  return { pageInfo, pageSize, activeRefs, selectOptions, showSelectOptions, dataTotal, moveRealInfo, pageList, clickHandler, changeNavHandle, changeInputHandle }
}
